home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gdb / gdb_18s.zoo / blockframe.c < prev    next >
C/C++ Source or Header  |  1992-03-25  |  10KB  |  401 lines

  1. /* Get info from stack frames;
  2.    convert between frames, blocks, functions and pc values.
  3.    Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
  4.  
  5. GDB is distributed in the hope that it will be useful, but WITHOUT ANY
  6. WARRANTY.  No author or distributor accepts responsibility to anyone
  7. for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.
  9. Refer to the GDB General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute GDB,
  12. but only under the conditions described in the GDB General Public
  13. License.  A copy of this license is supposed to have been given to you
  14. along with GDB so you can know your rights and responsibilities.  It
  15. should be in a file named COPYING.  Among other things, the copyright
  16. notice and this notice must be preserved on all copies.
  17.  
  18. In other words, go ahead and share GDB, but don't try to stop
  19. anyone else from sharing it farther.  Help stamp out software hoarding!
  20. */
  21.  
  22. #include "defs.h"
  23. #include "param.h"
  24. #include "symtab.h"
  25. #include "frame.h"
  26.  
  27. /* Address of end of first object file.
  28.    This file is assumed to be a startup file
  29.    and frames with pc's inside it
  30.    are treated as nonexistent.  */
  31.  
  32. CORE_ADDR first_object_file_end;
  33.  
  34. /* Address of innermost stack frame (contents of FP register) */
  35.  
  36. static FRAME current_frame;
  37.  
  38. struct block *block_for_pc ();
  39. CORE_ADDR get_pc_function_start ();
  40.  
  41. /* Return the innermost (currently executing) stack frame.  */
  42.  
  43. FRAME
  44. get_current_frame ()
  45. {
  46.   /* We assume its address is kept in a general register;
  47.      param.h says which register.  */
  48.  
  49.   return current_frame;
  50. }
  51.  
  52. void
  53. set_current_frame (frame)
  54.      FRAME frame;
  55. {
  56.   current_frame = frame;
  57. }
  58.  
  59. /* Return the frame that called FRAME.
  60.    If FRAME is the original frame (it has no caller), return 0.  */
  61.  
  62. FRAME
  63. get_prev_frame (frame)
  64.      FRAME frame;
  65. {
  66.   CORE_ADDR pointer;
  67.   /* The caller of "no frame" is the innermost frame.  */
  68.   if (frame == 0)
  69.     return get_current_frame ();
  70.  
  71.   /* Two macros defined in param.h specify the machine-dependent
  72.      actions to be performed here.  */
  73.   /* First, get the frame's chain-pointer.
  74.      If that is zero, the frame is the outermost frame.  */
  75.   pointer = FRAME_CHAIN (frame);
  76.   if (!FRAME_CHAIN_VALID (pointer, frame))
  77.     return 0;
  78.   /* If frame has a caller, combine the chain pointer and the frame's own
  79.      address to get the address of the caller.  */
  80.   return FRAME_CHAIN_COMBINE (pointer, frame);
  81. }
  82.  
  83. /* Return a structure containing various interesting information
  84.    about a specified stack frame.  */
  85.  
  86. struct frame_info
  87. get_frame_info (frame)
  88.      FRAME frame;
  89. {
  90.   static struct frame_info val;
  91.   FRAME current = get_current_frame ();
  92.   register FRAME frame1;
  93.  
  94.   val.frame = frame;
  95.  
  96.   if (frame == current)
  97.     {
  98.       val.pc = read_pc ();
  99.       val.next_frame = 0;
  100.     }
  101.   else 
  102.     {
  103.       for (frame1 = current; frame1; frame1 = get_prev_frame (frame1))
  104.     {
  105.       QUIT;
  106.       if (frame1 == frame)
  107.         break;
  108.  
  109.       val.pc = FRAME_SAVED_PC (frame1);
  110.       val.next_frame = frame1;
  111.     }
  112.     }
  113.  
  114.   return val;
  115. }
  116.  
  117. /* Return a structure containing various interesting information
  118.    about the frame that called FRAME.
  119.  
  120.    This is much faster than get_frame_info (get_prev_frame (FRAME))
  121.    because it does not need to search the entire stack
  122.    to find the frame called by the one being described -- that is FRAME.  */
  123.  
  124. struct frame_info
  125. get_prev_frame_info (next_frame)
  126.      FRAME next_frame;
  127. {
  128.   struct frame_info val;
  129.   register FRAME frame = get_prev_frame (next_frame);
  130.  
  131.   val.frame = frame;
  132.   val.next_frame = next_frame;
  133.  
  134.   if (next_frame == 0)
  135.     {
  136.       val.pc = read_pc ();
  137.     }
  138.   else 
  139.     {
  140.       val.pc = FRAME_SAVED_PC (next_frame);
  141.     }
  142.  
  143.   return val;
  144. }
  145.  
  146. CORE_ADDR
  147. get_frame_pc (frame)
  148.      FRAME frame;
  149. {
  150.   struct frame_info fi;
  151.   fi = get_frame_info (frame);
  152.   return fi.pc;
  153. }
  154.  
  155. /* Find the addresses in which registers are saved in FRAME.  */
  156.  
  157. void
  158. get_frame_saved_regs (frame_info_addr, saved_regs_addr)
  159.      struct frame_info *frame_info_addr;
  160.      struct frame_saved_regs *saved_regs_addr;
  161. {
  162.   FRAME_FIND_SAVED_REGS (*frame_info_addr, *saved_regs_addr);
  163. }
  164.  
  165. /* Return the innermost lexical block in execution
  166.    in a specified stack frame.  The frame address is assumed valid.  */
  167.  
  168. struct block *
  169. get_frame_block (frame)
  170.      FRAME frame;
  171. {
  172.   struct frame_info fi;
  173.  
  174.   fi = get_frame_info (frame);
  175.   return block_for_pc (fi.pc);
  176. }
  177.  
  178. struct block *
  179. get_current_block ()
  180. {
  181.   return block_for_pc (read_pc ());
  182. }
  183.  
  184. CORE_ADDR
  185. get_pc_function_start (pc)
  186.      CORE_ADDR pc;
  187. {
  188.   register struct block *bl = block_for_pc (pc);
  189.   register struct symbol *symbol;
  190.   if (bl == 0)
  191.     {
  192.       register int misc_index = find_pc_misc_function (pc);
  193.       if (misc_index >= 0)
  194.     return misc_function_vector[misc_index].address;
  195.       return 0;
  196.     }
  197.   symbol = block_function (bl);
  198.   bl = SYMBOL_BLOCK_VALUE (symbol);
  199.   return BLOCK_START (bl);
  200. }  
  201.  
  202. /* Return the symbol for the function executing in frame FRAME.  */
  203.  
  204. struct symbol *
  205. get_frame_function (frame)
  206.      FRAME frame;
  207. {
  208.   register struct block *bl = get_frame_block (frame);
  209.   if (bl == 0)
  210.     return 0;
  211.   return block_function (bl);
  212. }
  213.  
  214. /* Return the innermost lexical block containing the specified pc value,
  215.    or 0 if there is none.  */
  216.  
  217. struct block *
  218. block_for_pc (pc)
  219.      register CORE_ADDR pc;
  220. {
  221.   register struct block *b;
  222.   register int bot, top, half;
  223.   register struct symtab *s;
  224.   struct blockvector *bl;
  225.  
  226.   /* First search all symtabs for one whose file contains our pc */
  227.  
  228.   for (s = symtab_list; s; s = s->next)
  229.     {
  230.       bl = BLOCKVECTOR (s);
  231.       b = BLOCKVECTOR_BLOCK (bl, 0);
  232.       if (BLOCK_START (b) <= pc
  233. #ifdef atarist
  234. /* with gcc 1.34, there appears to be an extra symtab generated per file,
  235.    with no lines in it.  some kind of placeholder?  anyhow, we add a test
  236.    here to only return symtabs that have lines in them */
  237.       && ((LINETABLE(s)->nitems) > 0)
  238. #endif
  239.       && BLOCK_END (b) > pc)
  240.     break;
  241.     }
  242.  
  243.   if (s == 0)
  244.     return 0;
  245.  
  246.   /* Then search that symtab for the smallest block that wins.  */
  247.   /* Use binary search to find the last block that starts before PC.  */
  248.  
  249.   bot = 0;
  250.   top = BLOCKVECTOR_NBLOCKS (bl);
  251.  
  252.   while (top - bot > 1)
  253.     {
  254.       half = (top - bot + 1) >> 1;
  255.       b = BLOCKVECTOR_BLOCK (bl, bot + half);
  256.       if (BLOCK_START (b) <= pc)
  257.     bot += half;
  258.       else
  259.     top = bot + half;
  260.     }
  261.  
  262.   /* Now search backward for a block that ends after PC.  */
  263.  
  264.   while (bot >= 0)
  265.     {
  266.       b = BLOCKVECTOR_BLOCK (bl, bot);
  267.       if (BLOCK_END (b) > pc)
  268.     return b;
  269.       bot--;
  270.     }
  271.  
  272.   return 0;
  273. }
  274.  
  275. /* Return the function containing pc value PC.
  276.    Returns 0 if function is not known.  */
  277.  
  278. struct symbol *
  279. find_pc_function (pc)
  280.      CORE_ADDR pc;
  281. {
  282.   register struct block *b = block_for_pc (pc);
  283.   if (b == 0)
  284.     return 0;
  285.   return block_function (b);
  286. }
  287.  
  288. /* Finds the "function" (text symbol) that is smaller than PC
  289.    but greatest of all of the potential text symbols.  Sets
  290.    *NAME and/or *ADDRESS conditionally if that pointer is non-zero.
  291.    Returns 0 if it couldn't find anything, 1 if it did.  On a zero
  292.    return, *NAME and *ADDRESS are always set to zero.  On a 1 return,
  293.    *NAME and *ADDRESS contain real information.  */
  294.  
  295. int
  296. find_pc_partial_function (pc, name, address)
  297.      CORE_ADDR pc;
  298.      char **name;
  299.      CORE_ADDR *address;
  300. {
  301.   struct symbol *f;
  302.   int miscfunc;
  303.  
  304.   f = find_pc_function (pc);
  305.   if (f)
  306.   {
  307.       if (name)
  308.       *name = SYMBOL_NAME (f);
  309.       if (address)
  310.       *address = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
  311.       return 1;
  312.   }
  313.   else
  314.     /* Must be in the misc function stuff.  */
  315.     {
  316.       miscfunc = find_pc_misc_function (pc);
  317.       if (miscfunc == -1)
  318.       {
  319.       /* No available symbol.  */
  320.       if (name != 0)
  321.           *name = 0;
  322.       if (address != 0)
  323.           *address = 0;
  324.       return 0;
  325.       }
  326.       if (address)
  327.     *address = misc_function_vector[miscfunc].address;
  328.       if (name)
  329.     *name = misc_function_vector[miscfunc].name;
  330.       return 1;
  331.     }
  332. }
  333.  
  334. /* Find the misc function whose address is the largest
  335.    while being less than PC.  Return its index in misc_function_vector.
  336.    Returns -1 if PC is not in suitable range.  */
  337.  
  338. int
  339. find_pc_misc